#include "serverconnection.h"

// Creates and returns an object of ServerConnection type that has attributes that are passed to it via parameters
ServerConnection::ServerConnection(QString name, QString host, int port, QString authName, QString password, QString filterString)
{
    // The below 6 lines set the attributes of this object to those given to the constructor via parameters
    this->name = name;
    this->host = host;
    this->port = port;
    this->authName = authName;
    this->password = password;
    this->filterString = filterString;
    connected = false; // Not connected to server
    socket = new QTcpSocket(this); // Create a new QTcpSocket
    //socket->setObjectName(name);

    // Set up the authentication string
    authString = "user " + authName + " pass " + password + " vers QTAPRS v1 filter " + filterString + " \n";
    connect(socket, SIGNAL(readyRead()), this, SLOT(newDataFromConnection())); // Connect this socket's readyread signal to slot
}

ServerConnection::ServerConnection(QString name, QString host, int port, QString authName, QString password, QString filterString, bool writeEnabled)
{
    // The below 6 lines set the attributes of this object to those given to the constructor via parameters
    this->name = name;
    this->host = host;
    this->port = port;
    this->authName = authName;
    this->password = password;
    this->filterString = filterString;
    this->writeEnabled = writeEnabled;
    connected = false; // Not connected to server
    socket = new QTcpSocket(this); // Create a new QTcpSocket
    //socket->setObjectName(name);

    // Set up the authentication string
    authString = "user " + authName + " pass " + password + " vers QTAPRS v1 filter " + filterString + " \n";
    connect(socket, SIGNAL(readyRead()), this, SLOT(newDataFromConnection())); // Connect this socket's readyread signal to slot
}

// Deletes the connection and takes care of all of the logistical stuff
ServerConnection::~ServerConnection()
{
    disconnectFromServer(); // disconnect socket from server
    delete socket; // delete socket
}

// Forms a connection to the server that this object represents
void ServerConnection::connectToServer()
{
    socket->connectToHost(host,port,QAbstractSocket::ReadWrite);// connects to host
    socket->waitForConnected(30000); // Make sure we're connected (get rid of latency)
    qDebug() << "Socket State = " << socket->state();

    if(socket->state() != QAbstractSocket::ConnectedState){
        QApplication::beep(); // We are not connected, beep to warn user
        qDebug() << "NOT CONNECTED!!\n";
    }
    else{// we are connected
        connected = true;   // socket is connected
        qDebug() << "Authentication String = " << authString;
        authString.append("\n");
        writeToSocket(authString); // Send server authentication string
        qDebug() << "AuthString written to socket\n";
    }
}


// disconnect from the server this object represents
void ServerConnection::disconnectFromServer()
{
    connected = false;  // socket is not connected
    socket->disconnect(); // disconnect from server
    socket->close(); // close socket

    delete socket;
    socket = new QTcpSocket(this);
    connect(socket,SIGNAL(readyRead()), this, SLOT(newDataFromConnection()));
}

// Change the attributes of this connection
void ServerConnection::changeParameters(QString name, QString host, int port, QString authName, QString password, QString filterString)
{   // Change this objects local attributes
    this->name = name;
    this->host = host;
    this->port = port;
    this->authName = authName;
    this->password = password;
    this->filterString = filterString;
    socket->setObjectName(name);
}

// Write aprsPacket (given as parameter) to the socket
void ServerConnection::writeToSocket(QString aprsPacket)
{
    QByteArray block = aprsPacket.toAscii(); // allocate a bytearray to send aprsPacket with
    socket->write(block); // write block to socket
    qDebug() << "Wrote { " + aprsPacket + " } to server " + this->host + "\n";
}

// new packet has been received by connection
void ServerConnection::newDataFromConnection()
{
    emit this->newData(getPacket()); // emit the packet to whomever cares
    //qDebug() << "newData() emitted\n";
}

// returns the QString form of the packet received from the server
QString ServerConnection::getPacket()
{
    char buf[1024]; // Create a buffer of type char to hold packet
    memset(buf,0,1024); // Zeros out memory that buffer is located at
    socket->read(buf,1024); // reads data from socket and stores to buf
    QString string(buf); // casts the char buffer to a string
    //qDebug() << string.toUtf8();
    return string.toUtf8(); // returns the string that represents packet
}

// is this object currently connected to a server?
bool ServerConnection::isConnected()
{
    return this->connected; // returns true if connected or false if not connected
}

// Returns the name given to this connection
QString ServerConnection::getName()
{
    return this->name;
}

// Returns the hostname of this connection
QString ServerConnection::getHostName()
{
    return this->host;
}

// Returns the port that this connection uses
int ServerConnection::getPortNumber()
{
    return this->port;
}

// Returns the username used to authenticate with server
QString ServerConnection::getUserName()
{
    return this->authName;
}

// Returns password used to authenticate with server
QString ServerConnection::getPassword()
{
    return this->password;
}

// Returns the filterstring used to do server-side filtering of aprs data
QString ServerConnection::getFilterString()
{
    return this->filterString;
}

bool ServerConnection::isWriteEnabled()
{
    return this->writeEnabled;
}
